package com.xbongbong.crm.abstracts;

import com.alibaba.fastjson.JSON;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.parent.explain.FormDataUpdateGetExplainHandler;
import com.xbongbong.paas.help.OwnerAndCoUserHelp;
import com.xbongbong.paas.lowcode.LowCodeConfigService;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateGetVO;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.util.FormUtil;
import com.xbongbong.parent.abstracts.AbstractEditPageRenderService;
import com.xbongbong.parent.explain.FormDataAddFormExplainHandlerName;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormOwnerUniqueEnum;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.lowcodeconfig.pojo.dto.LowCodeConfigGetDTO;
import com.xbongbong.pro.lowcodeconfig.pojo.vo.LowCodeConfigGetVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.FundTransferEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/01/24 15:44
 */
@Component
public abstract class AbstractCrmEditPageRenderService extends AbstractEditPageRenderService<PaasFormEntityExt, PaasFormDataEntityExt> {

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private FormDataAddFormExplainHandlerName formDataAddFormExplainHandlerName;
    @Resource
    private FormDataUpdateGetExplainHandler formDataUpdateGetExplainHandler;
    @Resource
    private OwnerAndCoUserHelp ownerAndCoUserHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private LowCodeConfigService lowCodeConfigService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private RichTextService richTextService;

    @Override
    public PaasFormDataEntityExt getData(FormDataUpdateGetDTO formDataUpdateGetDTO) throws XbbException{
        String corpid = formDataUpdateGetDTO.getCorpid();
        Integer saasMark = formDataUpdateGetDTO.getSaasMark();
        Integer businessType = formDataUpdateGetDTO.getBusinessType();
        Long dataId = formDataUpdateGetDTO.getDataId();
        PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam( corpid, saasMark, businessType, dataId);
        // 加入富文本,本来想放在formDataHelp,但是RichTextService不在Saas包里在Paas包里,就先放外边了
        // 详情页加富文本放在里面了,参见AbstractCrmDetailBaseInfoService
        richTextService.addRichTextByDataId(dataId, corpid, formDataUpdateGetDTO.getFormId(), businessType, saasMark, paasFormDataEntityExt.getDel(), paasFormDataEntityExt.getData());
        if (paasFormDataEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        if (Objects.equals(paasFormDataEntityExt.getDel(), DelEnum.DELETE.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);

        }
        if (FlowStatusEnum.inApproval(paasFormDataEntityExt.getFlowStatus()) && !Objects.equals(businessType, XbbRefTypeEnum.DISTRIBUTOR_ACCOUNT.getCode())) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200020);
        }
        return paasFormDataEntityExt;
    }

    @Override
    public LowCodeConfigGetVO getLowCodeConfig(LowCodeConfigGetDTO lowCodeConfigGetDTO) throws XbbException {
        return  lowCodeConfigService.get(lowCodeConfigGetDTO);
    }

    @Override
    public void isApprovedEdit(FormDataUpdateGetDTO formDataUpdateGetDTO, PaasFormDataEntityExt dataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException {
        boolean fromCopy = Objects.nonNull(formDataUpdateGetDTO.getSaasSpecialParamPojo()) && Objects.equals(formDataUpdateGetDTO.getSaasSpecialParamPojo().getFromCopy(), BasicConstant.ONE);

        workflowFormDataOperationService.isApprovedEdit(fromCopy, paasFormEntityExt.getAppId(), paasFormEntityExt.getMenuId(), paasFormEntityExt.getId(), paasFormEntityExt.getCorpid(), paasFormEntityExt.getSaasMark(), paasFormEntityExt.getBusinessType(), dataEntity.getFlowStatus(), formDataUpdateGetDTO.getLoginUser());
    }


    @Override
    public PaasFormEntityExt getForm(FormDataUpdateGetDTO formDataUpdateGetDTO) throws XbbException {
        Long formId = formDataUpdateGetDTO.getFormId();
        String corpid = formDataUpdateGetDTO.getCorpid();
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
        if ( paasFormEntityExt == null ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        if ( Objects.equals(paasFormEntityExt.getEnable(), 0) || Objects.equals(paasFormEntityExt.getDel(), 1) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
        Integer businessType = formDataUpdateGetDTO.getBusinessType();
        paasFormModel.validateByPermission(paasFormEntityExt, formDataUpdateGetDTO.getLoginUser());
        FormUtil.handleFormEntity(paasFormEntityExt, paasFormEntityExt.getSaasMark(), businessType);
        return paasFormEntityExt;
    }

    @Override
    public List<FieldAttrEntity> getExplain(PaasFormEntityExt paasFormEntityExt, String corpid) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);
        if ( paasFormExplainEntity == null ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Integer businessType = paasFormExplainEntity.getBusinessType();
        List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        //根据套餐判断负责人属性
        Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
        boolean ultimateTag = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
        if(!ultimateTag && FormOwnerUniqueEnum.getDefaultBusinessList().contains(businessType)){
            //只有旗舰版支持负责人唯一设置，其他版本拿默认设置
            FormOwnerUniqueEnum formOwnerUniqueEnum = FormOwnerUniqueEnum.getFormOwnerUniqueByBus(businessType);
            Integer multiple = formOwnerUniqueEnum.getValue();
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                if(Objects.equals(fieldAttrEntity.getAttr(), FieldTypeEnum.OWNERID.getAlias())){
                    fieldAttrEntity.setMultiple(multiple);
                }
            }
        }
        return explainList;
    }

    @Override
    public HandlerExplainVO handleExplain(FormDataUpdateGetDTO formDataUpdateGetDTO, Map<String, UserEntity> userMap, PaasFormDataEntityExt paasFormDataEntityExt, List<FieldAttrEntity> explainList, PaasFormEntityExt form) throws XbbException {
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataUpdateGetDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(explainList);
        handlerExplainDTO.setPaasFormEntityExt(form);
        handlerExplainDTO.setFormData(paasFormDataEntityExt.getData());
        Integer saasMark = form.getSaasMark();
        Integer businessType = form.getBusinessType();

        // 获取协同人和负责人
        ownerAndCoUserHelp.getOwnerIdAndCoUserId(handlerExplainDTO, saasMark, businessType, paasFormDataEntityExt, userMap, DelEnum.NORMAL.getDel());
        List<String> ownerIds = handlerExplainDTO.getOwnerId();
        List<String> coUserIds = handlerExplainDTO.getCoUserId();

        HandlerExplainVO handlerExplainVO;
        SaasSpecialParamPojo saasSpecialParamPojo = formDataUpdateGetDTO.getSaasSpecialParamPojo();
        if ( Objects.nonNull(saasSpecialParamPojo) && Objects.equals(saasSpecialParamPojo.getFromCopy(), BasicConstant.ONE) ) {
            // 详情点击“复制”会调用此处渲染
            handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
        } else {
            handlerExplainVO = formDataUpdateGetExplainHandler.handleExplain(handlerExplainDTO);
        }
        List<String> unableEditMemo= Arrays.asList(I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD, Locale.US), I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD, Locale.CHINA));
        //团队成员上线之后负责人唯一跟套餐相关了
        List<Integer> allBusinessList = FormOwnerUniqueEnum.getAllBusinessList();
        Integer feeType = commonHelp.getCurrentCompanyPackage(formDataUpdateGetDTO.getCorpid());
        boolean teamOwnerUniqueTag = !Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType()) && allBusinessList.contains(businessType)
                && Objects.equals(DistributorMarkEnum.OTHER.getCode(), formDataUpdateGetDTO.getDistributorMark());
        // fix:18442 【移动端、web端】新建、编辑页面，不展示系统自动生成字段
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (unableEditMemo.contains(fieldAttrEntity.getUnableEditMemo())){
                fieldAttrEntity.setVisible(0);
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.FUND_TRANSFER.getCode())) {
                // TODO 后面移到自己的业务层去
                List<String> unEditableAttrList = FundTransferEnum.getUnEditableAttrList();
                if (unEditableAttrList.contains(fieldAttrEntity.getAttr())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
            }
            if (teamOwnerUniqueTag && Objects.equals(FieldTypeEnum.OWNERID.getAlias(), fieldAttrEntity.getAttr())) {
                fieldAttrEntity.setMultiple(FormOwnerUniqueEnum.getFormOwnerUniqueByBus(businessType).getValue());
            }
        }
        // 业务层字段解释处理
        businessHandleExplain(formDataUpdateGetDTO, handlerExplainVO.getHeadList(), form, paasFormDataEntityExt);
        handlerExplainVO.setOwnerId(ownerIds);
        handlerExplainVO.setCoUserId(coUserIds);
        return handlerExplainVO;
    }

    @Override
    public void formatSaasAttrToReturn(FormDataUpdateGetDTO formDataUpdateGetDTO, FormDataUpdateGetVO formDataUpdateGetVO, PaasFormEntityExt form, PaasFormDataEntityExt dataEntity) throws XbbException {
        formDataUpdateGetVO.setData(dataEntity);
        formDataUpdateGetVO.setPaasFormEntity(form);
    }
}
